package com.hex.ds.hdrs.period.task.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.hex.ds.hdrs.agent.service.AgentManager;
import com.hex.ds.hdrs.agent.service.AgentSession;
import com.hex.ds.hdrs.app.service.AppManager;
import com.hex.ds.hdrs.app.service.AppSession;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.constant.ErrorCode;
import com.hex.ds.hdrs.common.exception.BizException;
import com.hex.ds.hdrs.common.sort.SortQueue;
import com.hex.ds.hdrs.common.utils.HdrsDateUtil;
import com.hex.ds.hdrs.common.utils.ListUtil;
import com.hex.ds.hdrs.engine.manager.RunningManager;
import com.hex.ds.hdrs.engine.manager.ToDoManager;
import com.hex.ds.hdrs.engine.manager.ToRunManager;
import com.hex.ds.hdrs.period.job.po.JobTask;
import com.hex.ds.hdrs.period.job.po.PeriodJob;
import com.hex.ds.hdrs.period.job.po.PeriodJobDef;
import com.hex.ds.hdrs.period.job.service.PeriodJobDefService;
import com.hex.ds.hdrs.period.job.service.PeriodJobService;
import com.hex.ds.hdrs.period.task.po.PeriodTask;
import com.hex.ds.hdrs.period.task.po.TaskTrack;
import com.hex.ds.hdrs.period.task.util.TaskTrackHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Slf4j
@Component
public class TaskService {

    @Autowired
    private PeriodJobDefService periodJobDefService;

    @Autowired
    private PeriodTaskService periodTaskService;

    @Autowired
    private PeriodJobService periodJobService;

    @Autowired
    private TaskFinishService taskFinishService;

    @Autowired
    private ToRunManager toRunManager;

    @Autowired
    private ToDoManager toDoManager;

    @Autowired
    private RunningManager runningManager;

    @Autowired
    private AgentManager agentManager;

    @Autowired
    private AppManager appManager;

    @Value("${strategy.resNotEnough.type}")
    private String resNotEnoughStrategy;

    @Value("${strategy.resNotEnough.downNum}")
    private int resNotEnoughDownNum;

    @Value("${strategy.resNotEnough.delayTs}")
    private int resNotEnoughDelayTs;

    @Value("${strategy.sendFail.type}")
    private String sendFailStrategy;

    @Value("${strategy.sendFail.delayTs}")
    private int sendFailDelayTs;

    @Transactional(rollbackFor = Exception.class)
    public synchronized AgentSession updateTaskInfo(PeriodTask task, JobTask jobTask) {
        // 1、检查当前任务是否存在互斥任务
        checkMutex(task);
        // 2、检查当前任务所属应用的并发数和资源数是否有空闲
        AppSession appSession = appManager.getAppSession(task);
        // 3、获取一个可用的AgentSession
        AgentSession agentSession = appSession.getFitAgent(agentManager, jobTask, task);

        String execStTs = HdrsDateUtil.getCurTs();
        // 4.更新数据库中周期作业和周期任务实例信息
        updateTaskStatusToRunning(task, jobTask, agentSession, execStTs);

        //5. 更新内存中任务信息
        task.setAgentCode(agentSession.getAgentCode());
        task.setExecStTs(execStTs);

        //6. 更新session资源并发数
        agentSession.addTaskSession(task);
        appSession.addTaskSession(task);

        //7.将任务从可执行队列转移到正在执行队列
        toRunManager.toRunToRunning(task, Const.TRACK_TYPE_RUN_TO_RUNNING, runningManager);
        return agentSession;
    }

    /*
     * @Method: checkMutex <br>
     * @Param: [task] <br>
     * @Return: void <br>
     * @Description：检查当前任务是否存在互斥任务<br>
     * @Author： wz.li<br>
     * @Date： 2023/7/4 17:03 <br>
     * @Version： V2.0.2<br>
     */
    private void checkMutex(PeriodTask task) {
        log.debug("检查互斥作业/任务是否有在执行中【任务编码: {}】", task.getTaskCode());
        AppSession appSession = appManager.getValidAppSession(task.getAppCode());

        List<String> mutexTaskDefList = appSession.getMutexTaskCodeList();
        if (ListUtil.isEmpty(mutexTaskDefList)) {
            log.debug("该应用下无互斥任务【任务编码: {}】", task.getTaskCode());
            return;
        }
        if (mutexTaskDefList.contains(task.getTaskCode())) {
            for (String taskDefCode : mutexTaskDefList) {
                if (runningManager.isContainsTask(taskDefCode)) {
                    log.warn("任务不允许执行【任务编码: {}】存在互斥任务", task.getTaskCode());
                    String errorMsg = StrUtil.format(ErrorCode.ERROR_821000.getMessage(), taskDefCode);
                    throw new BizException(ErrorCode.ERROR_821000,errorMsg);
                }
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateTaskStatusToRunning(PeriodTask task, JobTask jobTask, AgentSession agentSession, String execStTs) {
        try {
            updatePeriodTaskInfo(task, agentSession.getAgentCode(), execStTs);
            updatePeriodJobInfo(task, jobTask, execStTs);
        } catch (Exception e) {
            log.error("【异常】【TaskService.updateTaskStatusToRunning】异常: {}", e.getMessage());
            throw new BizException(ErrorCode.ERROR_820006);
        }
    }

    private void updatePeriodTaskInfo(PeriodTask task, String agentCode, String execStTs) {
        Map<String, String> map = new HashMap<>(16);
        map.put("taskCode", task.getTaskCode());
        map.put("bizDate", task.getBizDate());
        map.put("agentCode", agentCode);
        map.put("execStTs", execStTs);
        map.put("taskStatus", Const.TASK_RUNNING);
        map.put("trackJson", JSONObject.toJSON(task.getTaskTrackMap()).toString());
        map.put("upTs", execStTs);
        this.periodTaskService.updateTask(map);
    }

    private void updatePeriodJobInfo(PeriodTask task, JobTask jobTask, String execStTs) {
        boolean isFirstTask = jobTask.isFirstTask(task);
        if (isFirstTask) {
            Map<String, String> jobMap = new HashMap<>(16);
            jobMap.put("jobCode", task.getJobCode());
            jobMap.put("bizDate", task.getBizDate());
            jobMap.put("jobStTs", execStTs);
            this.periodJobService.updateJob(jobMap);
        }
    }

    /**
     * @Method: taskRollBack
     * @Param: [errorCode, jobTask, task]
     * @Return: void
     * @Description： 任务回滚处理
     * @Author： jd.chen
     * @Date： 2021/6/19 10:02
     * @Version： V1.0
     */
    public void taskRollBack(String errorCode, JobTask jobTask, PeriodTask task, String errorMsg) {
        String jobCode = task.getJobCode();
        String taskCode = task.getTaskCode();
        String bizDate = task.getBizDate();
        log.debug("【taskRollBack】errorCode：{},taskCode:{},bizDate:{}", errorCode, taskCode, bizDate);
        if (runningManager.isContainsJob(jobCode)) {
            log.warn("任务到running队列，发送agent失败,taskCode【{}】【{}】", taskCode, bizDate);
            this.taskFinishService.taskExecFailDeal(jobTask, task, "任务到running队列，发送agent失败!");
            return;
        }
        SortQueue sortQueue = toRunManager.getSortQueue(task.getAppCode());
        if (errorCode.equals(ErrorCode.ERROR_820000.getCode())) {
            log.debug("任务回滚处理【app 不活动】【DispatcherExec.taskRollBack】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_820000.getMessage(), HdrsDateUtil.getCurTs()));
            sortQueue.addFirst(task);
        } else if (errorCode.equals(ErrorCode.ERROR_820002.getCode())) {
            log.debug("任务回滚处理【agent 不活动】【DispatcherExec.taskRollBack】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_820002.getMessage(), HdrsDateUtil.getCurTs()));
            sortQueue.addFirst(task);
        } else if (errorCode.equals(ErrorCode.ERROR_820001.getCode())) {
            log.debug("任务回滚处理【app 资源不够】【DispatcherExec.taskRollBack】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_820001.getMessage(), HdrsDateUtil.getCurTs()));
            this.resNotEnough(sortQueue, task);
        } else if (errorCode.equals(ErrorCode.ERROR_820003.getCode())) {
            log.debug("任务回滚处理【agent 资源不够】【DispatcherExec.taskRollBack】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_820003.getMessage(), HdrsDateUtil.getCurTs()));
            this.resNotEnough(sortQueue, task);
        } else if (errorCode.equals(ErrorCode.ERROR_820004.getCode())) {
            log.debug("任务回滚处理【任务的上游依赖 有未完成】【DispatcherExec.taskRollBack】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_820004.getMessage(), HdrsDateUtil.getCurTs()));
            toRunManager.toRunToToDo(task, Const.TRACK_TYPE_RUN_TO_DO, toDoManager);
        } else if (errorCode.equals(ErrorCode.ERROR_820005.getCode())) {
            // 测试中未出现异常到此的情况
            log.debug("任务回滚处理【任务发送 失败】【DispatcherExec.taskRollBack】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_820005.getMessage(), HdrsDateUtil.getCurTs()));
            this.sendAgentFail(sortQueue, task);
        } else if (errorCode.equals(ErrorCode.ERROR_820012.getCode())) {
            log.debug("任务回滚处理【任务为暂停状态，暂时不处理】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_820012.getMessage(), HdrsDateUtil.getCurTs()));
            sortQueue.addLast(task);
        } else if (errorCode.equals(ErrorCode.ERROR_821000.getCode())){
            log.debug("任务回滚处理【任务处理异常，存在互斥任务】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_821000.getMessage(), HdrsDateUtil.getCurTs()));
            sortQueue.addLast(task);
        } else if (errorCode.equals(ErrorCode.ERROR_821006.getCode())){
            log.debug("任务回滚处理【任务处理异常，还未到执行时间】======");
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : ErrorCode.ERROR_821006.getMessage(), HdrsDateUtil.getCurTs()));
            sortQueue.addLast(task);
        } else {
            log.info("任务回滚处理【DispatcherExec.taskRollBack】======{}:{}", errorCode,errorMsg);
            TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_ROLL_BACK", false, StrUtil.isNotEmpty(errorMsg) ? errorMsg : "DispatcherExec.taskRollBack", HdrsDateUtil.getCurTs()));
            sortQueue.addLast(task);
        }
    }

    /**
     * app 或 agent 资源不够  策略
     *
     * @param jobTaskQueue
     * @param task
     */
    public void resNotEnough(SortQueue jobTaskQueue, PeriodTask task) {
        log.warn("app 或 agent 资源不够【TaskService.resNotEnough】taskCode: {} bizDate: {}", task.getTaskCode(), task.getBizDate());
        try {
            if (Const.RES_NOT_ENOUGH_BACK_FIRST.equalsIgnoreCase(resNotEnoughStrategy)) {
                log.warn("添加回队首【TaskService.resNotEnough】=========》");
                TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_RES", false, "添加回队首", HdrsDateUtil.getCurTs()));
                jobTaskQueue.addFirst(task);
            } else if (Const.RES_NOT_ENOUGH_DOWN_SORT.equalsIgnoreCase(resNotEnoughStrategy)) {
                log.warn("需要降序【TaskService.resNotEnough】=========》");
                TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_RES", false, "需要降序", HdrsDateUtil.getCurTs()));
                jobTaskQueue.downSort(task, resNotEnoughDownNum);
            } else if (Const.RES_NOT_ENOUGH_DELAY_TS.equalsIgnoreCase(resNotEnoughStrategy)) {
                log.warn("需要等待时间【TaskService.resNotEnough】=========》");
                TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_RES", false, "需要等待时间", HdrsDateUtil.getCurTs()));
                jobTaskQueue.addToDelay(task, resNotEnoughDelayTs);
            } else {
                log.error("无效的处理类型【TaskService.resNotEnough】");
                throw new BizException(ErrorCode.ERROR_888000);
            }
        } catch (Exception e) {
            log.error("【TaskService.resNotEnough】异常: {}", e.getMessage());

        }
    }

    /**
     * 任务发送 失败 策略
     *
     * @param jobTaskQueue
     * @param task
     */
    public void sendAgentFail(SortQueue jobTaskQueue, PeriodTask task) {
        log.info("任务发送 失败【TaskService.sendAgentFail】=========》");
        try {
            int allowErrCount = task.getAllowErrCount();
            if (-1 == allowErrCount || task.getErrCount() <= allowErrCount) {
                if (Const.SEND_FAIL_DELAY_TS.equalsIgnoreCase(sendFailStrategy)) {
                    log.info("需要等待时间【TaskService.sendAgentFail】=========》");
                    TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_SEND_FAIL", false, "等待时间", HdrsDateUtil.getCurTs()));
                    jobTaskQueue.addToDelay(task, sendFailDelayTs);
                } else {
                    log.info("直接加回队首【TaskService.sendAgentFail】=========》");
                    TaskTrackHelper.addTaskTrack(task, new TaskTrack("DP_SEND_FAIL", false, "直接加回队首", HdrsDateUtil.getCurTs()));
                    jobTaskQueue.addFirst(task);
                }
            } else {
                log.warn("出错数超过允许出错数【TaskService.sendAgentFail】=========》");
                this.sendOverAllowErrCount(task);
            }
        } catch (Exception e) {
            log.error("【TaskService.sendAgentFail】异常:{}", e.getMessage());
        }
    }

    /**
     * 出错数超过允许出错数
     *
     * @param task
     */
    public void sendOverAllowErrCount(PeriodTask task) {
        log.info("出错数超过允许出错数【TaskService.sendOverAllowErrCount】=========》");
        try {
            // 添加任务轨迹
            TaskTrackHelper.addTaskTrack(task, TaskTrackHelper.dispatcherFail("任务发送agent失败,超过允许出错数!"));
            // 超过出错次数  更新DB状态异常
            Map<String, String> map = new HashMap<>(16);
            map.put("taskCode", task.getTaskCode());
            map.put("bizDate", task.getBizDate());
            map.put("taskStatus", Const.TASK_FAIL);
            map.put("trackJson", JSONObject.toJSON(task.getTaskTrackMap()).toString());
            this.updateTask(map);

            // 20210527 任务失败，更新作业为失败
            Map<String, String> jobMap = new HashMap<>(16);
            jobMap.put("jobCode", task.getJobCode());
            jobMap.put("bizDate", task.getBizDate());
            jobMap.put("jobStatus", Const.JOB_TO_DO);
            jobMap.put("upTs", HdrsDateUtil.getCurTs());
            this.periodJobService.updateJob(jobMap);

            // 可执行队列移除任务
            toRunManager.removeJob(task, "出错数超过允许出错数");
        } catch (Exception e) {
            log.error("【TaskService.sendOverAllowErrCount】异常: {}", e.getMessage());

        }
    }

    /**
     * 检查任务上游依赖是否完成  true：未完成  false：已完成
     *
     * @param task
     */
    public boolean checkUpJobIsFinish(PeriodTask task) {
        if (StringUtils.isEmpty(task.getDependTask()) && StringUtils.isEmpty(task.getDependJob())) {
            // 无依赖，无需db校验
            return false;
        } else {
            return this.periodTaskService.checkUpJobIsFinish(task);
        }
    }

    /**
     * @Method getUpDependErrorMsg <br>
     * @Param task
     * @Param msg <br>
     * @Return  <br>
     * @Description 上游依赖未完成error信息<br>
     * @Author Qiao jian<br>
     * @Date 2024/4/18 18:14 <br>
     * @Version V1.0<br>
     */
    public String getUpDependErrorMsg(PeriodTask task,String msg){
//        long startTime = System.currentTimeMillis(); // 请求发出时间
        String unDoneUpJobCode = getUnDoneUpJobInfo(task);
        String unDoneUpTaskCode = getUnDoneUpTaskInfo(task);
//        long endTime = System.currentTimeMillis(); // 响应到达时间
//        long responseTime = endTime - startTime; // 计算响应时间
//        log.info("Response Time:{} " , responseTime + " ms");
        if (StrUtil.isNotBlank(unDoneUpJobCode) || StrUtil.isNotBlank(unDoneUpTaskCode)){
            return StrUtil.format(msg,StrUtil.isNotBlank(unDoneUpJobCode) ? unDoneUpJobCode : "无", StrUtil.isNotBlank(unDoneUpTaskCode) ? unDoneUpTaskCode : "无");
        }
        return "";

    }

    /**
     * @Method getUnDoneUpJobInfo <br>
     * @Param task <br>
     * @Return  <br>
     * @Description 未完成依赖作业<br>
     * @Author Qiao jian<br>
     * @Date 2024/4/18 18:13 <br>
     * @Version V1.0<br>
     */
    public String getUnDoneUpJobInfo(PeriodTask task) {
        String dependJob = task.getDependJob();
        if (StringUtils.isBlank(dependJob)) {
            return "";
        }
        //所有上游依赖job实例（未生成实例的无法查到）
        List<PeriodJob> upDependJob = queryUpDependJob(task);
        //首先判断 是否有为生成示例的作业
        List<String> dependJobList = Arrays.asList(dependJob.split(","));
        Optional<String> firstMissingJobCode = dependJobList.stream()
                .filter(jobCode -> upDependJob.stream().noneMatch(upJob -> upJob.getJobCode().equals(jobCode)))
                .findFirst();
        if (firstMissingJobCode.isPresent()){
            return firstMissingJobCode.get();
        }
        //找出为完成的作业
        Optional<String> firstJobCodeWithStatus1 = upDependJob.stream()
                .filter(job -> job.getJobStatus().equals(Const.JOB_TO_DO)) // 筛选状态为1的PeriodJob
                .map(PeriodJob::getJobCode)
                .findFirst();
        return firstJobCodeWithStatus1.orElse("");
    }

    /**
     * @Method getUnDoneUpTaskInfo <br>
     * @Param task <br>
     * @Return  <br>
     * @Description 未完成依赖任务<br>
     * @Author Qiao jian<br>
     * @Date 2024/4/18 18:13 <br>
     * @Version V1.0<br>
     */
    public String getUnDoneUpTaskInfo(PeriodTask task) {
        String dependTask = task.getDependTask();
        if (StrUtil.isBlank(dependTask)){
            return "";
        }
        List<PeriodTask> upDependTask = queryUpDependTask(task);
        List<String> dependTaskList = Arrays.asList(dependTask.split(","));
        //未生成实例
        Optional<String> firstMissingTaskCode = dependTaskList.stream()
                .filter(taskCode -> upDependTask.stream().noneMatch(upJob -> upJob.getTaskCode().equals(taskCode)))
                .findFirst();
        if (firstMissingTaskCode.isPresent()){
            return firstMissingTaskCode.get();
        }
        //找出未完成的任务
        Optional<String> firstJobCodeWithStatus1 = upDependTask.stream()
                .filter(periodTask -> (!periodTask.getTaskStatus().equals(Const.TASK_SUCCESS) && !periodTask.getTaskStatus().equals(Const.TASK_HAND_SUCCESS)))
                .map(PeriodTask::getTaskCode)
                .findFirst();
        return firstJobCodeWithStatus1.orElse("");
    }

    /**
     * @Method getFirstValue <br>
     * @Param
     * @Param str <br>
     * @Return java.lang.String <br>
     * @Description 获取第一个值<br>
     * @Author jian.qiao<br>
     * @Date 2023/11/27 16:34 <br>
     * @Version V1.0<br>
     */
    public static String getFirstValue(String str) {
        if (str != null && !str.isEmpty()) {
            String[] values = str.split(",");
            if (values.length > 0) {
                return values[0];
            }
        }
        return null;
    }


    /**
     * @Method queryUpDependTask <br>
     * @Param
     * @Param task <br>
     * @Return java.util.List<com.hex.ds.hdrs.period.task.po.PeriodTask> <br>
     * @Description 查询上游依赖任务未完成列表<br>
     * @Author jian.qiao<br>
     * @Date 2023/11/22 16:08 <br>
     * @Version V1.0<br>
     */
    public List<PeriodTask> queryUpDependTask(PeriodTask task){
        return this.periodTaskService.upDependTaskList(task);
    }

    /**
     * @Method queryUpDependJob <br>
     * @Param
     * @Param task <br>
     * @Return java.util.List<com.hex.ds.hdrs.period.job.po.PeriodJob> <br>
     * @Description 查询上游依赖作业未完成列表 <br>
     * @Author jian.qiao<br>
     * @Date 2023/11/22 16:08 <br>
     * @Version V1.0<br>
     */
    public List<PeriodJob> queryUpDependJob(PeriodTask task){
        return this.periodTaskService.upDependJobList(task);
    }


    /**
     * 更新任务信息
     *
     * @param map
     */
    public void updateTask(Map map) {
        map.put("upTs", HdrsDateUtil.getCurTs());
        this.periodTaskService.updateTask(map);
    }

    /**
     * 更新作业信息
     *
     * @param map
     */
    public void updateJob(Map map) {
        this.periodJobService.updateJob(map);
    }

    /**
     * 查询一个业务日期的作业
     *
     * @param jobCode
     * @return
     */
    public PeriodJob qryNextDateJob(String jobCode) {
        return this.periodJobService.qryNextDateJob(jobCode);
    }

    /**
     * 查询一个业务日期的作业
     *
     * @param jobCode
     * @param bizDate
     * @return
     */
    public List<PeriodTask> qryNextDateTask(String jobCode, String bizDate) {
        return this.periodTaskService.qryTaskListInJob(jobCode, bizDate);
    }


    /*
     * @Method: checkRunTime <br>
     * @Param: [task] <br>
     * @Return: void <br>
     * @Description：DB判断任务是否到达执行时间点<br>
     * @Author： wz.li<br>
     * @Date： 2022/12/10 17:19 <br>
     * @Version： V2.0.2<br>
     */
    public void checkRunTime(PeriodTask periodTask) {
        Date runningTime = cn.hutool.core.date.DateUtil.date(cn.hutool.core.date.DateUtil.parse(periodTask.getBizDate()));
        runningTime = cn.hutool.core.date.DateUtil.offsetHour(runningTime, getOffsetHour(periodTask));
        if (cn.hutool.core.date.DateUtil.date().before(runningTime)) {
            throw new BizException(ErrorCode.ERROR_821006);
        }
    }

    /*
     * @Method: getOffsetHour <br>
     * @Param: [periodTask] <br>
     * @Return: java.lang.Integer <br>
     * @Description：获取任务偏移小时<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/28 15:59 <br>
     * @Version： V2.0.2<br>
     */
    private Integer getOffsetHour(PeriodTask periodTask) {
        if (periodTask.getOffsetHour() == null) {
            PeriodJobDef periodJobDef = periodJobDefService.getJobDefByJobCode(periodTask.getJobCode());
            periodTask.setOffsetHour(periodJobDef.getOffsetHour());
        }
        return periodTask.getOffsetHour();
    }

    /**
     * 查询全量作业
     *
     * @return
     */
    public List<PeriodJob> qryJobList() {
        return this.periodJobService.qryJobList();
    }

    /**
     * 获取全量的toDo任务队列
     *
     * @return
     */
    public List<PeriodTask> qryToDoTaskList() {
        return this.periodTaskService.qryToDoTaskList();
    }

    /**
     * 查询增量作业
     *
     * @return
     */
    public List<PeriodJob> qryJobList(String lastQryTs) {
        return this.periodJobService.qryJobList(lastQryTs);
    }

    /**
     * 获取增量的任务队列
     *
     * @return
     */
    public List<PeriodTask> qryToDoTaskList(String lastQryTs) {
        return this.periodTaskService.qryToDoTaskList(lastQryTs);
    }

    /**
     * 查询全量 最新完成作业
     *
     * @return
     */
    public List<PeriodJob> qryLstFnsJobList() {
        return this.periodJobService.qryLstFnsJobList();
    }

    /**
     * 获取全量--最新完成任务队列
     *
     * @return
     */
    public List<PeriodTask> qryLstFnsTaskList() {
        return this.periodTaskService.qryLstFnsTaskList();
    }

    /**
     * 查询增量 最新完成作业
     *
     * @return
     */
    public List<PeriodJob> qryLstFnsJobList(String lastQryTs) {
        return this.periodJobService.qryLstFnsJobList(lastQryTs);
    }

    /**
     * 获取增量--最新完成任务队列
     *
     * @return
     */
    public List<PeriodTask> qryLstFnsTaskList(String lastQryTs) {
        return this.periodTaskService.qryLstFnsTaskList(lastQryTs);
    }
}
